package hk.edu.polyu.comp.motioncapture.frontend;

import java.util.*;
import java.io.*;
import java.net.*;
import org.xvolks.jnative.misc.basicStructures.*;
import hk.edu.polyu.comp.motioncapture.*;

public class MotionCaptureFrontEnd implements Runnable {

	public static final boolean bActiveWindow = true;

	protected String host;
	protected int port;

	public static void main(String[] args) {
		if (args.length == 2 || args.length == 0) {
			try {
				MotionCaptureFrontEnd app;
				if (args.length == 2) {
					app = new MotionCaptureFrontEnd(args[0], Integer
							.parseInt(args[1]));
				} else {
					app = new MotionCaptureFrontEnd();
				}
				app.run();
			} catch (Exception ex) {
				ex.printStackTrace();
			}
		} else {
			System.out.println("Usage: MotionCaptureFrontEnd [ip port]");
		}
	}

	public MotionCaptureFrontEnd() throws Exception {
		this("localhost", 43419);
	}

	public MotionCaptureFrontEnd(String host, int port) throws Exception {
		this.host = host;
		this.port = port;
	}

	public void run() {
		try {
			int screenWidth = NativeWin32
					.GetSystemMetrics(NativeWin32.SM_CXSCREEN);
			int screenHeight = NativeWin32
					.GetSystemMetrics(NativeWin32.SM_CYSCREEN);
			System.out.println("Screen resolution: " + screenWidth + "x"
					+ screenHeight);

			Scanner keyb = new Scanner(System.in).useDelimiter("\n");

			System.out.println("Press ENTER to connect to " + host + ":" + port
					+ " ...");
			keyb.next();

			Socket socket = new Socket(host, port);
			System.out.println("Connected");
			BufferedReader in = new BufferedReader(new InputStreamReader(socket
					.getInputStream()));

			String ln;
			String[] ss;
			while (socket.isConnected()) {
				System.out.print("Received string: ");
				ln = in.readLine();
				System.out.println(ln);

				ss = ln.split("END")[0].split(" ");
				if (ss[0].equals("screen")) {
					System.out.println("screen");
				} else if (ss[0].equals("mouse_scroll_up")) {
					System.out.println("mouse_scroll_up");

					NativeWin32.mouse_event(new DWORD(
							NativeWin32.MOUSEEVENTF_WHEEL), new DWORD(0),
							new DWORD(0), new DWORD(NativeWin32.WHEEL_DELTA));

				} else if (ss[0].equals("mouse_scroll_down")) {
					System.out.println("mouse_scroll_down");

					NativeWin32.mouse_event(new DWORD(
							NativeWin32.MOUSEEVENTF_WHEEL), new DWORD(0),
							new DWORD(0), new DWORD(-NativeWin32.WHEEL_DELTA));

				} else if (ss[0].equals("mouseStatus_click")) {
					System.out.println("mouse click");

					NativeWin32.mouse_event(new DWORD(
							NativeWin32.MOUSEEVENTF_LEFTDOWN), new DWORD(0),
							new DWORD(0), new DWORD(0));

					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}

					NativeWin32.mouse_event(new DWORD(
							NativeWin32.MOUSEEVENTF_LEFTUP), new DWORD(0),
							new DWORD(0), new DWORD(0));

				} else if (ss[0].equals("mouse_move")) {
					if (ss.length == 3) {
						// int x = (int) (Double.parseDouble(ss[1]) / 65535.0 *
						// screenWidth);
						// int y = (int) (Double.parseDouble(ss[2]) / 65535.0 *
						// screenHeight);
						double x = Double.parseDouble(ss[1]);
						double y = Double.parseDouble(ss[2]);

						if (bActiveWindow) {
							HWND hwnd = NativeWin32.GetForegroundWindow();
							if (hwnd != null) {
								System.out.println("Hwnd: " + hwnd.getValue());

								RECT rect = NativeWin32.GetWindowRect(hwnd);
								if (rect != null) {
									System.out.println("RECT: " + rect);

									int windowWidth = rect.getRight()
											- rect.getLeft();
									int windowHeight = rect.getBottom()
											- rect.getTop();
									int windowX = rect.getLeft();
									int windowY = rect.getTop();

									x = (x / 65535.0 * (double) windowWidth)
											+ windowX;
									y = (y / 65535.0 * (double) windowHeight)
											+ windowY;

									// Convert screen coordinate to 65535x65535
									x = x / (double) screenWidth * 65535.0;
									y = y / (double) screenHeight * 65535.0;
								}
							}
						}
						System.out.println("mouse_move " + x + ", " + y);

						NativeWin32.mouse_event(new DWORD(
								NativeWin32.MOUSEEVENTF_ABSOLUTE
										| NativeWin32.MOUSEEVENTF_MOVE),
								new DWORD((int) x), new DWORD((int) y),
								new DWORD(0));

					} else {
						System.out.println("mouse_move args error!");
					}
				}
			}

			System.out.println("End");
			in.close();

		} catch (UnknownHostException ex) {
			ex.printStackTrace();
		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}
}
